<?php
declare (strict_types=1);

namespace app\api\controller;

use app\api\logic\LogicalProcess;
use app\api\model\DtsGame;
use app\api\model\Member;
use app\api\model\UserPointsLog;
use app\api\services\DtsService;
use app\common\Alisms;
use app\common\Txsms;
use Fund\Points\Add;
use lunzi\TpSms;
use phpDocumentor\Reflection\Type;
use think\cache\driver\Redis;
use think\Exception;
use think\facade\Log;
use wechat\WechatOauth;
use think\facade\Db;
use think\facade\Cache;

/**
 * 登录
 */
class Login extends Api
{
    /**
     * {@inheritdoc}
     * rules:
     * actions 控制器列表: * 全部控制器
     * roles 允许访问角色:
     * all 全部;
     * no_all 不允许任何人进;
     * login 登录(默认);
     * allow 验证规则:
     * no_checkTime 不验证时间戳;
     * no_checkSign  不验证签名;
     */
    protected $auth = [
        [
            'actions' => ['login', 'send', 'registerByPhone', 'ceshi'],
            'roles' => 'all',
            'allow' => [],
        ]
    ];

    public function initialize()
    {
        parent::initialize();
        $this->model = new Member();
    }

    /**
     * 注册接口
     * @param password 密码
     * @param repetitionPassword 重复密码
     * @param mobile 手机号
     * @param smsCode 手机验证码
     * @param inviteCode 邀请码
     */
    public function registerByPhone()
    {
        $data = request()->param();
//        if (is_empty($data['username'])) $this->error("用户账号不能为空", '', -1);
        if (is_empty($data['password'])) $this->error("密码不能为空", '', -1);
        if (is_empty($data['repetitionPassword'])) $this->error("确认密码不能为空", '', -1);
        if (is_empty($data['mobile']) || !is_mobile($data['mobile'])) $this->error("请输入正确的手机号码", '', -1);
        if (!checkPass($data['password'])) $this->error("密码强度太低,应包含字母,数字,并且在6位以上", '', -1);
        if ($data['password'] != $data['repetitionPassword']) $this->error("两次密码不一致", '', -1);
        if (strlen($data['password']) < 6 || strlen($data['password']) > 20) $this->error("密码长度应在6~20位", '', -1);
        //查询验证码开关是否开启
        $smsOpen = \app\api\model\Common::config("smsOpen");
        if ($smsOpen == 1) {
            if (is_empty($data['smsCode'])) $this->error("验证码不能为空", '', -1);
            //  检查验证码是否正确
//            $check_code = (new TpSms())
//                ->scene('register')
//                ->mobile($data['mobile'])
//                ->code($data['smsCode'])
//                ->check();
//            if (!$check_code) {
//                $this->error('验证码错误', '', -1);
//            }
        }
        $InviteOpen = \app\api\model\Common::config("InviteOpen");
        $inviteCode = getter($data, 'inviteCode');
        if ($InviteOpen == 1) {
            if (empty($inviteCode)) $this->error('请填写邀请码', '', -1);
        }

        //查询该账号是否存在
        $model = new Member();
        $is_member = $model->field('id')
            ->where('mobile', $data['mobile'])
            ->where('mark', 1)
            ->find();
        if ($is_member) $this->result("该手机号已注册，不可重复注册", [], -1);
        $group = $parentId = 0;
        if ($inviteCode) {
            $memberUp = Db::name("member")->where('invite_code', $inviteCode)->where('mark', 1)->field("group,id")->find();
            if (!$memberUp) return message("此邀请码无效", false);
            $group = $memberUp['group'] . "," . $memberUp['id'];
            if ($memberUp['group'] == 0) {
                $group = $memberUp['id'];
            }
            $parentId = $memberUp['id'];
        }
        $mobile = $data['mobile'];
        //邀请码
        $selfCode = get_random_str();
        Db::startTrans();
        try {
            $res = Db::name("member")->insertGetId([
                'username' => $mobile,
                'login_ip' => get_real_ip(),
                'update_time' => time(),
                'invite_code' => $selfCode,
                'nickname' => substr_replace($mobile, '****', 3, 4),
                'create_time' => time(),
                'password' => get_password($data['password'] . $mobile),
                "mobile" => $mobile,
                'status' => 1,
                'avatar' => "/default.png",
                'pid' => $parentId,
                'group' => $group,
                'login_time' => time(),
                'login_count' => 1,
                "random_uid" => get_random_str(5, 3)
            ]);
            if ($res != false) {
                //生成钱包
                Db::name("user_wallet")->insertAll([
                    [
                        "user_id" => $res,
                        "amount" => 0,
                        "freeze" => 0,
                        "type" => 1,
                    ],[
                        "user_id" => $res,
                        "amount" => 0,
                        "freeze" => 0,
                        "type" => 2,
                    ]
                ]);
                Db::commit();
                $this->result('注册成功', '', 0);
            } else {
                Db::rollback();
                $this->error("注册失败", [], -1);
            }
        } catch (Exception $e) {
            Db::rollback();
            $error = $e->getMessage();
            $this->error($error, [], -1);
        }
    }


    /**
     * 手机号登录
     */
    public function login()
    {
        $data = request()->param();
        $model = new Member();
        $is_member = $model
            ->where('username', $data['username'])
            ->where('mark', 1)
            ->find();
        if (!$is_member) $this->result('登陆失败，账号不存在', '', -1);
        //  检查验证码是否正确
        $check_code = (new TpSms())
            ->scene('login')
            ->mobile($data['username'])
            ->code($data['verification_code'])
            ->check();
        if (!$check_code) {
            $this->result('验证码错误', '', -1);
        }
//        if ($data['type'] == 1) {
////          //  检查验证码是否正确
////            $check_code = (new TpSms())
////                ->scene('login')
////                ->mobile($data['username'])
////                ->code($data['verification_code'])
////                ->check();
////            if (!$check_code) {
////                $this->result('验证码错误','',-1);
////            }
//        } else {
//            if (!$data['password']) $this->error('请输入密码');
//            $password = get_password($data['password'] . $data['username']);
//            if ($password != $is_member['password']) {
//                $this->result('登录密码不正确', '', -1);
//            }
//        }
        //更新用户登录次数和登录状态
        $model->where('id', $is_member['id'])->update([
            'login_count' => $is_member['login_count'] + 1,
            'update_time' => time()
        ]);
        $jwt = new \Jwt();
        $token = $jwt->getToken($is_member['id']);
        Cache::store("redis")->set('member_token_' . $is_member['id'], $token);
        $this->result('登陆成功', $token, 0);
    }


    //App微信登录
    public function wx_app_login()
    {
        $data = request()->param();
        $wechat = new WechatOauth();
        $member = $wechat->getUserinfo_app($data['access_token'], $data['openid']);
        $member = json_decode($member, true);
        if (!is_empty($member['openid'])) {
            $res = Member::wechat_login($member);
            if ($res['code'] == 0) {
                $this->success('登录成功', $res['data']);
            } else {
                $this->error('登录失败');
            }
        } else {
            $this->error('errcode:' . $member['errcode'] . ';errmsg:' . $member['errmsg']);
        }
    }

    /**
     * 发送验证码
     * @param phone 手机号
     * @param Type 类型
     */
    public function send()
    {
        $data = request()->param();
        $is_mobile = is_mobile($data['phone']);
        if (!$is_mobile) $this->error("请输入正确的手机号", [], -1);
        /**验证码类型
         * 1:register  注册
         * 2:login     登录
         * 3:loginPassword 修改登录密码
         * 4:handlePassword 修改支付密码
         */
        $smsType = [1 => "register", 2 => "login", 3 => "loginPassword", 4 => "handlePassword"];
        if (!array_key_exists($data['type'], $smsType)) $this->error("传入类型错误", [], -1);
        $config = Db::name('config_data')->where('config_id', 7)->select()->toArray();
        $arr = [];
        foreach ($config as $k => $v) {
            if ($v['code'] != 'id') {
                $arr[$v['code']] = $v['value'];
            }
        }
        $code = (new TpSms($arr))->scene($smsType[$data['type']])->mobile($data['phone'])->create();
        $res = (new Alisms())->ali_sms($data['phone'], $code);
        if ($res['code'] == 0) {
            $this->success('发送成功');
        } else {
            $this->error('发送失败', '', -1);
        }
    }


    /**
     * 退出登录
     */
    public function logOut()
    {
        $res = Member::where('id', $this->userId)->update([
            'update_time' => time()
        ]);
        if ($res !== false) {
            $redis = new Redis();
            $redis->delete('member_token_' . $this->userId);
            $this->result("退出登录成功", 0);
        } else {
            $this->result("退出登录成功", '', 1);
        }
    }


    public function ceshi()
    {
        (new LogicalProcess())->GetAccessToken();
        exit;
        $game = $this->getLastGame();

        try {
            $killer_index = $this->getKiller($game);
            //被刀房间的所有投注
            $total_killer_amount = $game->records()
                ->where('room_id', $killer_index)
                ->sum('amount');

            //所有房间的投注
            $total_amount = $game->records()->sum('amount');

            $total_people = 0;
            $total_bonus = 0;
            foreach ($game->records as $joinUser) {
                $total_people++;
                $joinUser->killer_room = $killer_index;

                //被刀房间的人
                if ($joinUser->room_id == $killer_index) {
                    $joinUser->state = 2;
                    $joinUser->save();
//                    $this->debugInfo($joinUser->user_id . ' kill');
                    continue;
                }

                //发放奖金
                $bonus = sprintf("%.2f", substr(sprintf("%.3f", $total_killer_amount * ($joinUser->amount / $total_amount)), 0, -2));
                if ($joinUser->user) {
                    //本金加利润
                    $add = new Add($joinUser->user, bcadd($bonus, (string)$joinUser->amount, 2), UserPointsLog::BUSINESS_TYPE_GAME_DTS_IN, ['target_id' => $joinUser->id]);
                    $add->action();
                }

                //累计共产生多少奖金
                $total_bonus = bcadd((string)$total_bonus, $bonus, 2);

                $joinUser->bonus = $bonus;
                $joinUser->state = 1;
                $joinUser->save();

                //更新自己的奖金
                DtsService::updateBonus($joinUser->user, $game, $bonus);
//                $this->debugInfo($joinUser->user_id . ' bonus ' . $bonus);
            }

            $game->state = 3;
            $game->end_time = time();
            $game->total_people = $total_people;
            $game->total_amount = $total_amount;
            $game->total_bonus = $total_bonus;
            $game->killer_room = $killer_index;
            $game->total_killer_amount = $total_killer_amount;
            $game->save();

            $this->killer_index = $killer_index;

            Db::commit();
            return true;
        } catch (\Exception $exception) {
            Db::rollback();
//            $this->debugInfo($exception->getMessage());
            Log::error($exception->getMessage());
            return false;
        }
//        $uid = 4;
//        $game_id = Cache::store("redis")->get('game_dts_last_game_id');
//
//        $game = DtsGame::find($game_id);
//        if (!$game) {
//            return '';
//        }
//        $timer = $game->end_time - time();
//        //房间人数限制
//        $max_people = DtsService::$max_people;
//        $user_list = DtsService::getGameUserList($game);
//        $join_people = DtsService::getGameUserBettingList($user_list);
//        $gameData = DtsService::getUserGameData($game, $uid);
//
//        $data = [
//            'user_id'             => $uid,
//            'game_id'             => $game_id,
//            'start_time'          => $game->start_time ?? 0, //开始时间
//            'end_time'            => $game->end_time ?? 0, //结束时间
//            'state'               => $game->state,// 状态：1:进行中 2:开始倒计时 3:结束
//            'timer'               => max($timer, 0), // 剩余秒数
//            'killer_room'         => $game->killer_room, // 本期去的房间
//            'pre_killer_room'     => $game->pre_killer_room,//上期去的房间
//            'join_people'         => count($join_people), // 加入的人
//            'max_people'          => $max_people, // 最大人数
//            'total_killer_amount' => $game->total_killer_amount, //杀手去的房间总投注
//            'user_bonus'          => $gameData->bonus ?? 0, //
//            'user_amount'         => $gameData->amount ?? 0, //
//            'user_list'           => $user_list, // 用户列表
//            'room_list'           => DtsService::calcRoomAmount($user_list), // 用户列表
//            'timestamp'           => time()
//        ];
//        return json_encode($data);
    }

    public function getKiller(DtsGame $game): int
    {
        $room_ids = $game->records()->column('room_id');
        return $room_ids[array_rand($room_ids, 1)];
    }

    public function getLastGame()
    {
        return DtsGame::where('state', 2)
            ->with('records')
//            ->where('end_time', '<=', time())
            ->find();
    }


}
